﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Security;
using System.Collections.Specialized;
using Nortec.Security.BusinessComponents;
using System.Configuration.Provider;
using Nortec.Security.BusinessEntities;

namespace Nortec.Security
{
    public class SqlServerRoleProvider : RoleProvider
    {
        #region Declarations
        private int applicationId;
        private string applicationName;
        private string companyName;
        private string dataSourceName;

        public int ApplicationId
        {
            get
            {
                return applicationId;
            }
            set
            {
                this.applicationId = value;
            }
        }
        public override string ApplicationName
        {
            get
            {
                return applicationName;
            }
            set
            {
                this.applicationName = value;
            }
        }
        public string CompanyName
        {
            get
            {
                return companyName;
            }
            set
            {
                this.companyName = value;
            }
        }
        public string DataSourceName
        {
            get
            {
                return dataSourceName;
            }
            set
            {
                this.dataSourceName = value;
            }
        }
        #endregion

        #region Methods:Public
        public override void Initialize(string name, NameValueCollection config){
            BCSecurity securityObject = new BCSecurity();

            DataSourceName = config["dataSourceName"];
            CompanyName = config["companyName"];
            ApplicationName = config["applicationName"];

            int companyId = Convert.ToInt32(config["companyId"]); //securityObject.GetCompanyId(CompanyName);
            ApplicationId = securityObject.GetApplicationId(ApplicationName, companyId);
        }
        public override void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            foreach (string username in usernames)
            {
                AddUserToRole(username, roleNames);
            }
        }
        public override void CreateRole(string roleName)
        {
            BCSecurity securityObject = new BCSecurity();
            int idRole = securityObject.CreateRole(roleName, "", ApplicationId);
            if (idRole == 0)
                throw new ProviderException("El rol que está tratando de agregar ya existe. Por favor seleccione otro nombre para el nuevo rol.");
        }
        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
        {
            BCSecurity securityObject = new BCSecurity();
            bool success = securityObject.DeleteRole(roleName, ApplicationId, throwOnPopulatedRole);
            if (throwOnPopulatedRole && !success)
                throw new ProviderException("El rol no pudo ser borrado debido a que existen usuarios asociados a el");
            
            return success;
        }
        public override string[] FindUsersInRole(string roleName, string usernameToMatch)
        {
            BCSecurity securityObject = new BCSecurity();
            BEUsuario.UsuarioDataTable usuarios = securityObject.FindUsersInRole(roleName, usernameToMatch, applicationId);
            string[] usernames = new string[usuarios.Count];
            for (int i = 0; i < usuarios.Count; i++)
                usernames[i] = usuarios[i].lit_usuario_username;

            return usernames;
        }
        public override string[] GetAllRoles()
        {
            BCSecurity securityObject = new BCSecurity();
            BERol.RolDataTable roles = securityObject.GetAllRoles(applicationId);
            string[] nombresRol = new string[roles.Count];
            for (int i = 0; i < roles.Count; i++)
                nombresRol[i] = roles[i].lit_rol_nombre;

            return nombresRol;

        }
        public override string[] GetRolesForUser(string username)
        {
            BCSecurity securityObject = new BCSecurity();
            BERol.RolDataTable roles = securityObject.GetRolesForUser(username, applicationId);
            string[] nombresRol = new string[roles.Count];
            for (int i = 0; i < roles.Count; i++)
                nombresRol[i] = roles[i].lit_rol_nombre;

            return nombresRol;
        }
        public override string[] GetUsersInRole(string roleName)
        {
            BCSecurity securityObject = new BCSecurity();
            BEUsuario.UsuarioDataTable usuarios = securityObject.GetUsersInRole(roleName, applicationId);
            string[] usernames = new string[usuarios.Count];
            for (int i = 0; i < usuarios.Count; i++)
                usernames[i] = usuarios[i].lit_usuario_username;

            return usernames;
        }
        public override bool IsUserInRole(string username, string roleName)
        {
            BCSecurity securityObject = new BCSecurity();
            return securityObject.IsUserInRole(username, roleName, applicationId);
            
        }
        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            BCSecurity securityObject = new BCSecurity();
            bool success = securityObject.RemoveUsersFromRoles(usernames, roleNames, ApplicationId);
            if (!success)
                throw new ProviderException("Uno de los roles o usuarios especificados no existe en la base de datos");
        }
        public override bool RoleExists(string roleName)
        {
            BCSecurity securityObject = new BCSecurity();
            BERol.RolDataTable roles = securityObject.GetRole(roleName, ApplicationId);
            return (roles.Count > 0);
        }
        #endregion

        #region Methods: Non-Public
        private void AddUserToRole(string username, string[] roleNames)
        {
            BCSecurity securityObject = new BCSecurity();

            foreach (string roleName in roleNames)
                securityObject.AddUserToRole(username, roleName, ApplicationName, CompanyName);

        }
        #endregion
       
    }
}
